﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using MyTimeLine.Models;

namespace MyTimeLine.Util
{
    public static class GerenciadorPaginacao
    {
        

        #region TamanhoPagina

        public static int TamanhoPagina
        {
            get
            {
                try
                {
                    return Int32.Parse(ConfigurationManager.AppSettings["TotalProdPorPagina"] ?? "10");
                }
                catch
                {
                    return 10;
                }
            }
        }

        #endregion

        #region TotalPaginas

        public static int TotalPaginas(int totalRegs)
        {
            int totalPaginas = totalRegs / TamanhoPagina;
            if ((totalPaginas % TamanhoPagina) > 0)
                totalPaginas++;
            return totalPaginas;
        }

        #endregion

        #region Pagina

        /// <summary>
        /// Retorna um objeto Iquerable paginado com a quantidade de pagina default
        /// </summary>
        /// <typeparam name="T">Typo da Consulta</typeparam>
        /// <typeparam name="TResult">Consulta</typeparam>
        /// <param name="obj">Obj da Consulta</param>
        /// <param name="page">Pagina desejada</param>
        /// <param name="orderSelector">Order by</param>
        /// <param name="asc">Ascendente ou não</param>
        /// <returns></returns>
        public static IQueryable<T> Pagina<T, TResult>(this IQueryable<T> obj, int page,
                                                       Expression<Func<T, TResult>> orderSelector, bool asc)
            //, out int rowsCount)
        {
            return Pagina(obj, page, TamanhoPagina, orderSelector, asc);
        }

        /// <summary>
        /// Retorna um objeto Iquerable paginado 
        /// </summary>
        /// <typeparam name="T">Typo da Consulta</typeparam>
        /// <typeparam name="TResult">Consulta</typeparam>
        /// <param name="obj">Obj da Consulta</param>
        /// <param name="page">Pagina desejada</param>
        /// <param name="pageSize">Tamanho de resitros por pagina</param>
        /// <param name="orderSelector">Order by</param>
        /// <param name="asc">Ascendente ou não</param>
        /// <returns></returns>
        public static IQueryable<T> Pagina<T, TResult>(this IQueryable<T> obj, int page, int pageSize,
                                                       Expression<Func<T, TResult>> orderSelector, bool asc)
            //, out int rowsCount)
        {
            //rowsCount = obj.Count();
            int innerRows = (page - 1) * pageSize;
            if (asc)
            {
                if (orderSelector != null) return obj.OrderBy(orderSelector).Skip(innerRows).Take(pageSize).AsQueryable();
            }
            else
            {
                if (orderSelector != null)
                    return obj.OrderByDescending(orderSelector).Skip(innerRows).Take(pageSize).AsQueryable();
            }

            return obj.Skip(innerRows).Take(pageSize).AsQueryable();
        }

        #endregion

        #region RetornarListaPaginacao

        /// <summary>
        /// Retona as "páginas" de uma paginação 
        /// </summary>
        /// <param name="totalReg">Total de Registros</param>
        /// <param name="currentActionName">Nome da Action</param>
        /// <param name="currentControllerName">Nome do Conatrolador</param>
        /// <param name="paginaAtual">Pagina atual</param>
        /// <returns></returns>
        public static List<Paginacao> RetornarListaPaginacao(int totalReg, string currentActionName,
                                                             string currentControllerName, int paginaAtual)
        {
            List<Paginacao> paginas = new List<Paginacao>();
            int totalPg = TotalPaginas(totalReg);
            for (var i = 1; i <= totalPg; i++)
            {

                paginas.Add(new Paginacao
                                {
                                    ActionName = currentActionName,
                                    ControllerName = currentControllerName,
                                    Pagina = i.ToString(),
                                    IsAtual = i == paginaAtual

                                });
            }
            return paginas;
        }

        #endregion

       
    }
}